﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Xml.Schema;
using System.Xml;
using System.Qizx.Api;

namespace System.Qizx.Xdm {
    internal class XdmName : IXdmSchemaInfo {
        // Fields
        private int _hashCode;
        private string _localName;
        private string _name;
        internal XdmName _next;
        private IQName _qname;
        private string _ns;
        internal XdmDocument _ownerDocument;
        private string _prefix;

        // Fields
        private XdmSchemaInfo _schemaInfo;

        internal static XdmName Create(string prefix, string localName, string ns, XdmDocument ownerDoc, XdmName next) {
            return new XdmName(prefix, localName, ns, ownerDoc, next);
        }

        // Methods
        internal XdmName(string prefix, string localName, string ns, XdmDocument ownerDoc, XdmName next) {
            this._prefix = prefix;
            this._localName = localName;
            this._ns = ns;
            this._name = null;
            this._ownerDocument = ownerDoc;
            this._next = next;
        }

        internal void Update(string prefix, string localName, string ns) {
            this._prefix = prefix;
            this._localName = localName;
            this._ns = ns;
            _name = null;
            _hashCode = 0;
        }

        internal void Update(IXdmSchemaInfo schemaInfo) {
            if (schemaInfo == null)
                _schemaInfo = null;
            else {
                this.Validity = schemaInfo.Validity;
                this.IsDefault = schemaInfo.IsDefault;
                this.IsNil = schemaInfo.IsNil;
                this.MemberType = schemaInfo.MemberType;
                this.SchemaType = schemaInfo.SchemaType;
                this.SchemaElement = schemaInfo.SchemaElement;
                this.SchemaAttribute = schemaInfo.SchemaAttribute;
                this.DataType = schemaInfo.DataType;
            }
        }

        public bool Equals(IXdmSchemaInfo schemaInfo) {
            if (this.Validity == XmlSchemaValidity.NotKnown && (schemaInfo == null || schemaInfo.Validity == XmlSchemaValidity.NotKnown)) {
                return true;
            } else if (schemaInfo == null) {
                return false;
            } else {
                return this.Validity == schemaInfo.Validity && this.IsDefault == schemaInfo.IsDefault && this.IsNil == schemaInfo.IsNil
                    && this.MemberType == schemaInfo.MemberType && this.SchemaType == schemaInfo.SchemaType
                    && this.SchemaElement == schemaInfo.SchemaElement && this.SchemaAttribute == schemaInfo.SchemaAttribute
                    && this.DataType == schemaInfo.DataType;
            }
        }


        // Properties
        public bool IsDefault {
            get {
                return _schemaInfo == null ? false : _schemaInfo.IsDefault;
            }
            set {
                if (_schemaInfo == null)
                    _schemaInfo = new XdmSchemaInfo();
                _schemaInfo.IsNil = value;
            }
        }

        public XmlSchemaDatatype DataType {
            get { return _schemaInfo == null ? null : _schemaInfo.DataType; }
            set {
                if (value != null || _schemaInfo == null) {
                    if (_schemaInfo == null)
                        _schemaInfo = new XdmSchemaInfo();
                    _schemaInfo.DataType = value;
                }
            }
        }

        public bool IsNil {
            get {
                return _schemaInfo == null ? false : _schemaInfo.IsNil;
            }
            set {
                if (_schemaInfo == null)
                    _schemaInfo = new XdmSchemaInfo();
                _schemaInfo.IsNil = value;
            }
        }

        public XmlSchemaSimpleType MemberType {
            get {
                return _schemaInfo == null ? null : _schemaInfo.MemberType;
            }
            set {
                if (value != null || _schemaInfo == null) {
                    if (_schemaInfo == null)
                        _schemaInfo = new XdmSchemaInfo();
                    _schemaInfo.MemberType = value;
                }
            }
        }

        public XmlSchemaAttribute SchemaAttribute {
            get {
                return _schemaInfo == null ? null : _schemaInfo.SchemaAttribute;
            }
            set {
                if (value != null || _schemaInfo == null) {
                    if (_schemaInfo == null)
                        _schemaInfo = new XdmSchemaInfo();
                    _schemaInfo.SchemaAttribute = value;
                }
            }
        }

        public XmlSchemaElement SchemaElement {
            get {
                return _schemaInfo == null ? null : _schemaInfo.SchemaElement;
            }
            set {
                if (value != null || _schemaInfo == null) {
                    if (_schemaInfo == null)
                        _schemaInfo = new XdmSchemaInfo();
                    _schemaInfo.SchemaElement = value;
                }
            }
        }

        public XmlSchemaType SchemaType {
            get {
                return _schemaInfo == null ? null : _schemaInfo.SchemaType;
            }
            set {
                if (value != null || _schemaInfo == null) {
                    if (_schemaInfo == null)
                        _schemaInfo = new XdmSchemaInfo();
                    _schemaInfo.SchemaType = value;
                }
            }
        }

        public XmlSchemaValidity Validity {
            get {
                return _schemaInfo == null ? XmlSchemaValidity.NotKnown : _schemaInfo.Validity;
            }
            set {
                if (value != XmlSchemaValidity.NotKnown || _schemaInfo == null) {
                    if (_schemaInfo == null)
                        _schemaInfo = new XdmSchemaInfo();
                    _schemaInfo.Validity = value;
                }
            }
        }

        public override int GetHashCode() {
            if (_hashCode == 0)
                _hashCode = this._localName.GetHashCode();
            return _hashCode;
        }

        public override bool Equals(object obj) {
            if (this.GetHashCode() != obj.GetHashCode()) return false;
            XdmName name = obj as XdmName;
            return name != null && this.Prefix == name.Prefix && this.NamespaceURI == name.NamespaceURI;
        }

        // Properties
        public string LocalName {
            get {
                return this._localName;
            }
        }

        public string Name {
            get {
                if (this._name == null) {
                    if (this._prefix.Length > 0) {
                        if (this._localName.Length > 0) {
                            string array = this._prefix + ":" + this._localName;
                            lock (this._ownerDocument.NameTable) {
                                if (this._name == null) {
                                    this._name = this._ownerDocument.NameTable.Add(array);
                                }
                                goto Label_0092;
                            }
                        }
                        this._name = this._prefix;
                    } else {
                        this._name = this._localName;
                    }
                }
            Label_0092:
                return this._name;
            }
        }

        public IQName InternalQName {
            get {
                if (_qname == null)
                    _qname = IQName.GetQName(this._ns, this._localName);
                return _qname;
            }
        }

        public string NamespaceURI {
            get {
                return this._ns;
            }
        }

        public XdmDocument OwnerDocument {
            get {
                return this._ownerDocument;
            }
        }

        public string Prefix {
            get {
                return this._prefix;
            }
        }

    }


}
